package com.cskaoyan.wordmemorize.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cskaoyan.wordmemorize.converter.RolePermissionConverter;
import com.cskaoyan.wordmemorize.dao.entity.PermissionDO;
import com.cskaoyan.wordmemorize.dao.entity.RoleDO;
import com.cskaoyan.wordmemorize.dao.entity.RolePermissionDO;
import com.cskaoyan.wordmemorize.dao.mapper.PermissionMapper;
import com.cskaoyan.wordmemorize.dao.mapper.RoleMapper;
import com.cskaoyan.wordmemorize.dao.mapper.RolePermissionMapper;
import com.cskaoyan.wordmemorize.dto.admin.*;
import com.cskaoyan.wordmemorize.request.PageRequest;
import com.cskaoyan.wordmemorize.request.PermissionCommand;
import com.cskaoyan.wordmemorize.request.RoleCommand;
import com.cskaoyan.wordmemorize.request.RolePermissionCommand;
import com.cskaoyan.wordmemorize.service.RolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermissionDO> implements RolePermissionService {
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    PermissionMapper permissionMapper;
    @Autowired
    RolePermissionMapper rolePermissionMapper;
    @Autowired
    private RolePermissionService rolePermissionService;
    @Autowired
    RolePermissionConverter rolePermissionConverter;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePermissions(PermissionCommand command) {
        Deque<PermissionCommand> stack = new ArrayDeque<>();
        stack.push(command);

        while (!stack.isEmpty()) {
            PermissionCommand current = stack.pop();
            PermissionDO permissionDO = new PermissionDO();

            // 修正点：移除对"-1"的特殊排除条件
            String parentPerm = current.getParentPermission();
            if (parentPerm != null && !parentPerm.trim().isEmpty()) {
                // 直接转换所有非空字符串（包括"-1"）
                permissionDO.setParentPermission(Long.parseLong(parentPerm));
            }

            // 设置其他字段（保持不变）
            permissionDO.setName(current.getName());
            permissionDO.setPermissionAlias(current.getPermissionAlias());
            permissionDO.setPermissionType(current.getPermissionType());
            permissionDO.setPermissionCode(current.getPermissionCode());
            permissionDO.setDesc(current.getDesc());
            permissionDO.setPath(current.getPath());
            permissionDO.setAccessType(current.getAccessType());

            permissionMapper.insert(permissionDO);
            Long currentId = permissionDO.getId();

            List<PermissionCommand> children = current.getChildren();
            if (children != null && !children.isEmpty()) {
                for (PermissionCommand child : children) {
                    child.setParentPermission(currentId.toString());
                    stack.push(child);
                }
            }
        }
    }

    @Override
    public List<PermissionDTO> getPermissions() {
        // 1. 查询所有未删除的权限记录
        List<PermissionDO> permissionDOList = permissionMapper.selectList(
                new LambdaQueryWrapper<PermissionDO>()
                        .eq(PermissionDO::getIsDeleted, 0)
        );

        // 2. 使用转换器转换为DTO列表
        List<PermissionDTO> permissionDTOList = rolePermissionConverter.employeePermissionDO2DTO(permissionDOList);

        // 3. 创建ID到DTO的映射
        Map<String, PermissionDTO> permissionMap = new HashMap<>();
        for (PermissionDTO dto : permissionDTOList) {
            // 初始化children列表
            if (dto.getChildren() == null) {
                dto.setChildren(new ArrayList<>());
            }
            permissionMap.put(dto.getId(), dto);
        }

        // 4. 构建权限森林
        List<PermissionDTO> forest = new ArrayList<>();
        for (PermissionDTO dto : permissionDTOList) {
            String parentId = dto.getParentPermission();
            if ("-1".equals(parentId)) {
                // 根节点直接加入森林
                forest.add(dto);
            } else {
                // 非根节点挂载到父节点
                PermissionDTO parent = permissionMap.get(parentId);
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(dto);
                }
            }
        }

        return forest;
    }

    @Transactional
    @Override
    public DeletePermissionOperateDTO deletePermission(Long permissionId) {
        // 1. 构建查询Wrapper
        QueryWrapper<PermissionDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", permissionId);
        queryWrapper.eq("is_deleted", 0); // 只查询未删除的记录

        // 2. 查询权限记录
        PermissionDO permissionDO = permissionMapper.selectOne(queryWrapper);
        if (permissionDO == null) {
            return null; // 权限不存在或已被删除
        }

        // 3. 构建更新Wrapper进行逻辑删除
        UpdateWrapper<PermissionDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("is_deleted", 1); // 标记为已删除
        updateWrapper.eq("id", permissionId);
        updateWrapper.eq("is_deleted", 0); // 确保只更新未删除的记录

        // 4. 执行更新（返回影响行数）
        int updateCount = permissionMapper.update(null, updateWrapper);

        if (updateCount == 0) {
            return null; // 更新失败（并发场景下可能已被其他操作删除）
        }

        // 5. 转换并返回操作日志DTO
        return rolePermissionConverter.toDeletePermissionOperateDTO(permissionDO);
    }

    @Transactional
    @Override
    public void updatePermission(PermissionCommand command) {
        Deque<PermissionCommand> stack = new ArrayDeque<>();
        stack.push(command);

        while (!stack.isEmpty()) {
            PermissionCommand current = stack.pop();

            // 创建更新对象
            PermissionDO permissionDO = new PermissionDO();

            // 设置父权限ID（包括处理"-1"的情况）
            String parentPerm = current.getParentPermission();
            if (parentPerm != null && !parentPerm.trim().isEmpty()) {
                permissionDO.setParentPermission(Long.parseLong(parentPerm));
            } else {
                // 明确处理null或空字符串情况
                permissionDO.setParentPermission(null);
            }

            // 设置其他字段
            permissionDO.setName(current.getName());
            permissionDO.setPermissionAlias(current.getPermissionAlias());
            permissionDO.setPermissionType(current.getPermissionType());
            permissionDO.setPermissionCode(current.getPermissionCode());
            permissionDO.setDesc(current.getDesc());
            permissionDO.setPath(current.getPath());
            permissionDO.setAccessType(current.getAccessType());

            // 创建更新条件 - 使用当前节点的ID
            UpdateWrapper<PermissionDO> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", Long.parseLong(current.getId()));

            // 执行更新 - 使用当前节点的ID作为条件
            permissionMapper.update(permissionDO, updateWrapper);

            // 处理子节点
            List<PermissionCommand> children = current.getChildren();
            if (children != null && !children.isEmpty()) {
                for (PermissionCommand child : children) {
                    // 设置子节点的父权限为当前节点的ID
                    child.setParentPermission(current.getId());
                    stack.push(child);
                }
            }
        }
    }

    @Override
    public PageDTO<RoleDTO> getRoleList(PageRequest pageRequest) {
// 获取请求参数
        Integer pageNum = pageRequest.getPageNum();
        Integer count = pageRequest.getCount();
        String keyword = pageRequest.getKeyword();

        // 初始化分页对象（默认查询第一页，每页10条）
        Page<RoleDO> page = new Page<>(1, 10);
        if (pageNum != null && count != null) {
            page = new Page<>(pageNum, count);
        }

        // 构建查询条件
        QueryWrapper<RoleDO> wrapper = new QueryWrapper<>();
        // 添加未删除条件
        wrapper.eq("is_deleted", 0);

        // 添加关键词模糊查询条件
        if (StringUtils.isNotBlank(keyword)) {
            wrapper.and(w -> w.like("name", keyword)
                    .or()
                    .like("description", keyword));
        }

        // 执行分页查询
        Page<RoleDO> rolePage = roleMapper.selectPage(page, wrapper);

        // 转换为DTO列表
        List<RoleDTO> roleDTOList = rolePage.getRecords().stream()
                .map(roleDO -> {
                    RoleDTO dto = new RoleDTO();
                    dto.setId(String.valueOf(roleDO.getId()));
                    dto.setName(roleDO.getName());
                    dto.setDescription(roleDO.getDescription());
                    return dto;
                })
                .collect(Collectors.toList());

        // 构建返回结果
        PageDTO<RoleDTO> result = new PageDTO<>();
        result.setPageList(roleDTOList);
        result.setTotalCount(rolePage.getTotal());

        return result;
    }

    @Override
    public void addRole(RoleCommand command) {
        RoleDO roleDO = new RoleDO();
        roleDO.setName(command.getName());
        roleDO.setDescription(command.getDescription());
        roleMapper.insert(roleDO);
    }

    @Override
    public void updateRole(RoleCommand roleCommand) {
        RoleDO roleDO = new RoleDO();
        roleDO.setName(roleCommand.getName());
        roleDO.setDescription(roleCommand.getDescription());
        UpdateWrapper<RoleDO> roleUpdateWrapper = new UpdateWrapper<>();
        roleUpdateWrapper.eq("id", Long.parseLong(roleCommand.getId()));
        roleMapper.update(roleDO, roleUpdateWrapper);
    }

    @Override
    public void updateRolePermission(RolePermissionCommand command) {
        String roleId = command.getRoleId();
        List<String> permissionIds = command.getPermissions();

        // 1. 逻辑删除该角色原有权限
        UpdateWrapper<RolePermissionDO> deleteWrapper = new UpdateWrapper<>();
        deleteWrapper.eq("role_id", roleId)
                .set("is_deleted", 1); // 标记为已删除
        rolePermissionMapper.update(null, deleteWrapper);

        // 2. 插入新的权限关系（如果权限列表非空）
        if (!CollectionUtils.isEmpty(permissionIds)) {
            List<RolePermissionDO> newPermissions = new ArrayList<>();
            for (String permissionId : permissionIds) {
                RolePermissionDO rp = new RolePermissionDO();
                rp.setRoleId(Long.parseLong(roleId));
                rp.setPermissionId(Long.parseLong(permissionId));
                rp.setIsDeleted(0); // 新记录标记为未删除
                newPermissions.add(rp);
            }

            // 批量插入新权限
            rolePermissionService.saveBatch(newPermissions);
        }
    }

    @Override
    public RolePermissionDTO getRolePermissionList(Long roleId) {
        // 1. 查询所有未删除的权限
        QueryWrapper<PermissionDO> permissionWrapper = new QueryWrapper<>();
        permissionWrapper.eq("is_deleted", 0);
        List<PermissionDO> allPermissions = permissionMapper.selectList(permissionWrapper);

        // 2. 查询角色已授权的权限ID列表
        QueryWrapper<RolePermissionDO> rolePermissionWrapper = new QueryWrapper<>();
        rolePermissionWrapper.select("permission_id")
                .eq("role_id", roleId)
                .eq("is_deleted", 0);
        List<RolePermissionDO> rolePermissions = rolePermissionMapper.selectList(rolePermissionWrapper);
        List<String> assignedPermissions = new ArrayList<>();
        for (RolePermissionDO rp : rolePermissions) {
            assignedPermissions.add(String.valueOf(rp.getPermissionId()));
        }

        // 3. 将DO转换为DTO并建立ID映射
        Map<Long, PermissionDTO> permissionMap = new HashMap<>();
        List<PermissionDTO> permissionDTOs = new ArrayList<>();

        for (PermissionDO permission : allPermissions) {
            PermissionDTO dto = new PermissionDTO();
            dto.setId(String.valueOf(permission.getId()));
            dto.setParentPermission(
                    permission.getParentPermission() != null ?
                            String.valueOf(permission.getParentPermission()) : "-1"
            );
            dto.setName(permission.getName());
            dto.setPermissionAlias(permission.getPermissionAlias());
            dto.setPermissionType(permission.getPermissionType());
            dto.setPermissionCode(permission.getPermissionCode());
            dto.setDesc(permission.getDesc());
            dto.setPath(permission.getPath());
            dto.setAccessType(permission.getAccessType());
            dto.setChildren(new ArrayList<>());

            permissionMap.put(permission.getId(), dto);
            permissionDTOs.add(dto);
        }

        // 4. 构建树形结构
        List<PermissionDTO> tree = new ArrayList<>();
        for (PermissionDTO dto : permissionDTOs) {
            String parentIdStr = dto.getParentPermission();
            Long parentId = "-1".equals(parentIdStr) ? -1L : Long.parseLong(parentIdStr);

            if (parentId == -1L) {
                tree.add(dto);
            } else {
                PermissionDTO parent = permissionMap.get(parentId);
                if (parent != null && parent.getChildren() != null) {
                    parent.getChildren().add(dto);
                }
            }
        }

        // 5. 组装返回结果
        RolePermissionDTO result = new RolePermissionDTO();
        result.setSystemPermissions(tree);
        result.setAssignedPermissions(assignedPermissions);

        return result;
    }

    @Override
    public DeleteRoleOperateDTO deleteRole(Long roleId) {
        // 1. 根据ID查询角色信息（只查询未删除的记录）
        QueryWrapper<RoleDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", roleId)
                .eq("is_deleted", 0); // 确保未删除
        RoleDO role = roleMapper.selectOne(queryWrapper);

        if (role == null) {
            return null; // 角色不存在或已被删除
        }

        // 2. 执行逻辑删除（使用UpdateWrapper）
        UpdateWrapper<RoleDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("is_deleted", 1)
                .eq("id", roleId)
                .eq("is_deleted", 0); // 防止重复删除
        int rows = roleMapper.update(null, updateWrapper);

        // 3. 构造返回结果
        if (rows > 0) {
            DeleteRoleOperateDTO dto = new DeleteRoleOperateDTO();
            dto.setId(role.getId());
            dto.setName(role.getName());
            return dto;
        } else {
            throw new RuntimeException("删除失败");
        }
    }

    @Override
    public DeleteRolePermissionOperateDTO deleteRolePermission(Long roleId, Long permissionId) {
        // 1. 查询所有权限数据用于构建权限树
        List<PermissionDO> allPermissions = permissionMapper.selectList(null);

        // 2. 构建父子权限映射关系 (parentId -> childrenIds)
        Map<Long, List<Long>> permissionTree = new HashMap<>();
        for (PermissionDO permission : allPermissions) {
            Long parentId = permission.getParentPermission();
            if (parentId != null) {
                permissionTree.computeIfAbsent(parentId, k -> new ArrayList<>())
                        .add(permission.getId());
            }
        }

        // 3. 收集所有需要删除的权限ID (包括传入的permissionId及其所有子权限)
        Set<Long> permissionIdsToDelete = new HashSet<>();
        Queue<Long> queue = new LinkedList<>();
        queue.add(permissionId);

        while (!queue.isEmpty()) {
            Long currentId = queue.poll();
            permissionIdsToDelete.add(currentId);

            // 将当前权限的子权限加入队列
            if (permissionTree.containsKey(currentId)) {
                for (Long childId : permissionTree.get(currentId)) {
                    if (!permissionIdsToDelete.contains(childId)) {
                        queue.add(childId);
                    }
                }
            }
        }

        // 4. 删除角色权限关联关系
        QueryWrapper<RolePermissionDO> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId)
                .in("permission_id", permissionIdsToDelete);
        rolePermissionMapper.delete(wrapper);

        // 5. 查询当前权限信息用于返回结果
        String permissionAlias = null;
        for (PermissionDO permission : allPermissions) {
            if (permission.getId().equals(permissionId)) {
                permissionAlias = permission.getPermissionAlias();
                break;
            }
        }

        // 6. 构建返回对象
        DeleteRolePermissionOperateDTO result = new DeleteRolePermissionOperateDTO();
        result.setRoleId(roleId);
        result.setPermissionId(permissionId);
        result.setPermissionAlias(permissionAlias);

        return result;
    }
}
